package com.michaelbulava.TFS.actions;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import com.michaelbulava.TFS.Messages;
import com.michaelbulava.TFS.tasks.vc.UndoPendingChangesTask;
import com.michaelbulava.TFS.vcs.TFSVcs;
import com.michaelbulava.TFS.vcs.exceptions.NotConnectedToTFS;
import com.michaelbulava.TFS.vcs.exceptions.TFSException;
import com.michaelbulava.TFS.vcs.internal.WorkstationHelper;
import com.michaelbulava.TFS.vcs.utils.TFSFileUtil;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.ChangeType;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.PendingChange;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by MichaelA on 11/14/2015.
 */
public class UndoPendingChangesAction extends OnlineRequiredAction {
    @Override
    public void actionPerformed(AnActionEvent e) {
        final Project project = (Project)e.getData(CommonDataKeys.PROJECT);
        final VirtualFile[] files = VcsUtil.getVirtualFiles(e);

        if (Messages.showYesNoDialog(project
                , MessageFormat.format(Messages.getString("UndoPendingChangesAction.ConfirmationFormat"),
                        new Object[] { files.length })
                , Messages.getString("UndoPendingChangesAction.ConfirmationTitle")) == Messages.YES){
            UndoPendingChangesTask task = new UndoPendingChangesTask(project, files);
            ProgressManager.getInstance().run(task);
        }
    }

    @Override
    public void update(AnActionEvent e){

        Project project = (Project)e.getData(CommonDataKeys.PROJECT);
        VirtualFile[] files = VcsUtil.getVirtualFiles(e);
        List<FilePath> myFilePaths = TFSFileUtil.getFilePaths(files);
        if (isOnline(project, files)){
            e.getPresentation().setEnabled(isEnabled(project, myFilePaths));
        } else{
            e.getPresentation().setEnabled(false);
        }
    }

    private static boolean isEnabled(final Project project, List<FilePath> files){
        TFSVcs vcs = TFSVcs.getInstance(project);
        //Check that the files aren't ignored first.
        for(FilePath file : files){
            if (vcs.isIgnoredFile(file))
                return false;
        }

        final List<Boolean> multiWorkspaceChecks = new ArrayList<Boolean>();
        try {
            WorkstationHelper.processByWorkspaces(files, true, project, new WorkstationHelper.VoidDelegateProcess() {
                @Override
                public void executeRequest(Workspace workspace, List<FilePath> localPaths) throws TFSException {
                    PendingChange[] pendingChanges = workspace.getPendingChanges(TFSFileUtil
                            .getItemSpecs(project, workspace, localPaths), true).getPendingChanges();
                    boolean hasChanges = false;
                    for(FilePath file : localPaths){
                        for(PendingChange change : pendingChanges){
                            if (change.getLocalItem().equals(file.getPath())){
                                if (!change.getChangeType().contains(ChangeType.NONE)){
                                    hasChanges = true;
                                }
                                break;
                            }
                        }
                    }
                    multiWorkspaceChecks.add(hasChanges);
                }

            });
        } catch (TFSException e) {
            e.printStackTrace();
        }
        //If all items are changed the menu item should be enable, otherwise it shouldn't.
        for(Boolean b : multiWorkspaceChecks){
            if (!b)
                return false;
        }
        return true;
    }
}
